﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;

namespace CoderJoe
{
	public class Workspace
		: IUnityContainer
	{
		private IUnityContainer Container { get; set; }

		public Workspace()
		{
			Container = new UnityContainer();
			// Register self
			Container.RegisterInstance(this, new ContainerControlledLifetimeManager());
		}

		#region IUnityContainer Members

		public IUnityContainer RegisterType<T>(params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType<T>(injectionMembers);
		}

		public IUnityContainer RegisterType<TFrom, TTo>(params InjectionMember[] injectionMembers) where TTo : TFrom
		{
			return Container.RegisterType<TFrom, TTo>(injectionMembers);
		}

		public IUnityContainer RegisterType<TFrom, TTo>(LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers) where TTo : TFrom
		{
			return Container.RegisterType<TFrom, TTo>(lifetimeManager, injectionMembers);
		}

		public IUnityContainer RegisterType<TFrom, TTo>(string name, params InjectionMember[] injectionMembers) where TTo : TFrom
		{
			return Container.RegisterType<TFrom, TTo>(name, injectionMembers);
		}

		public IUnityContainer RegisterType<TFrom, TTo>(string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers) where TTo : TFrom
		{
			return Container.RegisterType<TFrom, TTo>(name, lifetimeManager, injectionMembers);
		}

		public IUnityContainer RegisterType<T>(LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType<T>(lifetimeManager, injectionMembers);
		}

		public IUnityContainer RegisterType<T>(string name, params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType<T>(name, injectionMembers);
		}

		public IUnityContainer RegisterType<T>(string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType<T>(name, lifetimeManager, injectionMembers);
		}

		public IUnityContainer RegisterType(Type t, params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType(t, injectionMembers);
		}

		public IUnityContainer RegisterType(Type from, Type to, params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType(from, to, injectionMembers);
		}

		public IUnityContainer RegisterType(Type from, Type to, string name, params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType(from, to, name, injectionMembers);
		}

		public IUnityContainer RegisterType(Type from, Type to, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType(from, to, lifetimeManager, injectionMembers);
		}

		public IUnityContainer RegisterType(Type t, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType(t, lifetimeManager, injectionMembers);
		}

		public IUnityContainer RegisterType(Type t, string name, params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType(t, name, injectionMembers);
		}

		public IUnityContainer RegisterType(Type t, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType(t, name, lifetimeManager);
		}

		public IUnityContainer RegisterType(Type from, Type to, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
		{
			return Container.RegisterType(from, to, name, lifetimeManager, injectionMembers);
		}

		public IUnityContainer RegisterInstance<TInterface>(TInterface instance)
		{
			return Container.RegisterInstance<TInterface>(instance);
		}

		public IUnityContainer RegisterInstance<TInterface>(TInterface instance, LifetimeManager lifetimeManager)
		{
			return Container.RegisterInstance<TInterface>(instance, lifetimeManager);
		}

		public IUnityContainer RegisterInstance<TInterface>(string name, TInterface instance)
		{
			return Container.RegisterInstance<TInterface>(name, instance);
		}

		public IUnityContainer RegisterInstance<TInterface>(string name, TInterface instance, LifetimeManager lifetimeManager)
		{
			return Container.RegisterInstance<TInterface>(name, instance, lifetimeManager);
		}

		public IUnityContainer RegisterInstance(Type t, object instance)
		{
			return Container.RegisterInstance(t, instance);
		}

		public IUnityContainer RegisterInstance(Type t, object instance, LifetimeManager lifetimeManager)
		{
			return Container.RegisterInstance(t, instance, lifetimeManager);
		}

		public IUnityContainer RegisterInstance(Type t, string name, object instance)
		{
			return Container.RegisterInstance(t, name, instance);
		}

		public IUnityContainer RegisterInstance(Type t, string name, object instance, LifetimeManager lifetime)
		{
			return Container.RegisterInstance(t, name, instance, lifetime);
		}

		public T Resolve<T>()
		{
			return Container.Resolve<T>();
		}

		public T Resolve<T>(string name)
		{
			return Container.Resolve<T>(name);
		}

		public object Resolve(Type t)
		{
			return Container.Resolve(t);
		}

		public object Resolve(Type t, string name)
		{
			return Container.Resolve(t, name);
		}

		public IEnumerable<T> ResolveAll<T>()
		{
			return Container.ResolveAll<T>();
		}

		public IEnumerable<object> ResolveAll(Type t)
		{
			return Container.ResolveAll(t);
		}

		public T BuildUp<T>(T existing)
		{
			return Container.BuildUp<T>(existing);
		}

		public T BuildUp<T>(T existing, string name)
		{
			return Container.BuildUp<T>(existing, name);
		}

		public object BuildUp(Type t, object existing)
		{
			return Container.BuildUp(t, existing);
		}

		public object BuildUp(Type t, object existing, string name)
		{
			return Container.BuildUp(t, existing, name);
		}

		public void Teardown(object o)
		{
			Container.Teardown(o);
		}

		public IUnityContainer AddExtension(UnityContainerExtension extension)
		{
			return Container.AddExtension(extension);
		}

		public IUnityContainer AddNewExtension<TExtension>() where TExtension : UnityContainerExtension, new()
		{
			return Container.AddNewExtension<TExtension>();
		}

		public TConfigurator Configure<TConfigurator>() where TConfigurator : IUnityContainerExtensionConfigurator
		{
			return Container.Configure<TConfigurator>();
		}

		public object Configure(Type configurationInterface)
		{
			return Container.Configure(configurationInterface);
		}

		public IUnityContainer RemoveAllExtensions()
		{
			return Container.RemoveAllExtensions();
		}

		public IUnityContainer Parent
		{
			get { return Container.Parent; }
		}

		public IUnityContainer CreateChildContainer()
		{
			return Container.CreateChildContainer();
		}

		#endregion

		#region IDisposable Members
		private bool IsDisposing { get; set; }

		protected void Dispose(bool disposing)
		{
			if (IsDisposing == false)
			{
				IsDisposing = true;
				if (Container != null)
					Container.Dispose();
			}
		}

		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		~Workspace()
		{
			Dispose(false);
		}
		#endregion
	}
}
